
////////Liquid_level_sensor//////////


//#include  "iotv30_config.h"


#include "cjson_api_readAttr.h"
#include "iot_node_func.h"
#include "iotv30_config.h"
#include "test_mode.h"
// #include "iot_node.h"

#include "uart_printf.h"
#include <string.h>

#include "dev_liquid_level.h"





// 有效量程	1000mm
// 死区长度	上死区51mm，测杆死区40mm
// 测杆总长度	 1091mm+2mm



////注意：改变 数组 liquid_iot_id_table[liquid_index_end]的定义-----需要同步更新  枚举变量的定义 liquid_attr_index_e-------
const  uint16_t  liquid_iot_id_table[liquid_index_end]=
{
    //iot_id(hex)	,	name	R/W	变化上报	分类	数据类型	范围	单位	默认值		
    //	运行参数					
    0x0500	,//	液位报警信息	RO	是	运行参数	uint32_t		
    0x0501	,//	液位	RO	否	运行参数	uint32_t		0.01mm
    0x0502	,//	温度	RO	否	运行参数	int16_t		0.01℃------------ 0x0502

    //配置参//数							
    0x0600	,//	液位设备地址	R/W	否	配置参数	uint8_t	0~255	
    0x0601	,//	液位报警使能	R/W	否	配置参数	uint32_t		
    0x0602	,//	液位设备通道编号	R/W	否	配置参数	uint8_t	0~31	
            //				
    0x0604	,//	液位过低阈值	R/W	否	配置参数	uint32_t		0.01mm
    0x0605	,//	液位过高阈值	R/W	否	配置参数	uint32_t		0.01mm

    //---ver1.32--debug----------
    0x0606	,//1542	thTL	温度过低阈值	R/W	否	配置参数	int16_t	-32768~32767	0.01℃
    0x0607	,//1543	thTH	温度过高阈值	R/W	否	配置参数	int16_t	-32768~32767	0.01℃
    0x0608	,//1544	oilChkInterval	监测时间	R/W	否	配置参数	uint32_t		sec
    0x0609	,//1545	thOilConsume	液位异常值	R/W	否	配置参数	uint32_t		0.01mm


    //产品信息						
    0x0801	,//	软件版本	RO	否	软件版本	string	最大32字节	
    0x0802	,//	硬件版本	RO	否	硬件版本	string	最大32字节	
    0x0803	,//	产品型号	RO	否	产品型号	string	最大32字节	
    0x0804	,//	生产信息	RO	否	生产信息	string	最大32字节	
    0x0805	,//	厂家信息	RO	否		string	最大32字节	

};




 static liquid_attr_t liquid_obj[LIQUID_NODE_NUM_MAX];   /////下标与 配置节点数据结构一一对应 iot_NodeConfigObj_u   iot_NodeConfigObj;


static  liquid_attr_t liquid_attr_default={
    /////无报警信息
    .data.alarm.bit={
        .under_level  = 0,
        .over_level   = 0,
        .under_temper = 0,
        .over_temper  = 0,
    },

/////------测试数据-------------------------
    .data.level_mm = 50728, //0.01mm
    .data.temper   = 3712,    //温度  1℃ 

// MEI Type	0eH	MEI类型
// Read Device Id	01H	读取基本设备识别码

// 从机返回数据可以查询
// “公司识别码”为：KANGYU
// “产品代码”为：KYDM
// “版本号为”V3.30

/////------56H	版本号‘V’--------------
    .info.soft_ver="V3.30",
    .info.hard_ver="MEI-0e",// MEI Type	0eH	MEI类型

    .info.product_model="KYDM",       //Object Value	4bH	产品代码‘K’59H	‘Y’44H	‘D’4dH	‘M’
    .info.production_info="id-01",    //// Read Device Id	01H	读取基本设备识别码
    .info.manufacturer="KANGYU",     //4Bh==公司识别码’K’----广东新会康宇测控仪器仪表工程有限公司


    .config={//default value, do not delete

        .alarm_enable.bit={    /////报警使能无效
            .under_level  = 0,
            .over_level   = 0,
            .under_temper = 0,
            .over_temper  = 0,
           },

        .under_level_th  = 99000,//液位  0.01mm
        .over_level_th   = 20000,//液位  0.01mm
        .under_temper_th = -20,//温度  1℃ 
        .over_temper_th  = 90,//温度  1℃ 

       .addr    = 1,
       .channel = dev_chan_485_2,

    },


};






/**
 * @brief 
 * 
 */
void liquid_param_init(void)
{
 #if 0   
    snprintf(liquid_attr.info.soft_ver, sizeof(liquid_attr.info.soft_ver),"%s sv%04X %s",SDK_VER_STR,app_get_ver(),__DATE__);
    snprintf(liquid_attr.info.hard_ver, sizeof(liquid_attr.info.hard_ver),"%s",HARDWARE_STR);
    snprintf(liquid_attr.info.production_info, sizeof(liquid_attr.info.production_info),"%s","2024-08-p01");
#endif

}



//还需要检测配置参数是否合理----设备地址，通道编号---量程
uint8_t liquid_add_obj(uint8_t idx,uint8_t channel,uint8_t addr)
{

//还需要检测配置参数是否合理----设备地址，通道编号---量程
//  liquid_max_scale_0_01mm   (100000U)    //1000mm===1000x100 (0.01mm)

    LOG_NAME();

   if( (addr>liquid_max_dev_addr) || (channel>liquid_max_channel) )
   {
        return 0;
   }



    liquid_attr_default.config.addr    = addr;
    liquid_attr_default.config.channel = channel;

    liquid_set_obj( idx, (liquid_attr_t*)&liquid_attr_default ) ; 

 return 1;

}




/**
 * @brief 根据下标，获取iot_id 的编号
 * 
 * @param idx 
 */
uint16_t  liquid_get_iot_id(uint8_t idx)
{
    return  liquid_iot_id_table[idx] ;
}




/**
 * @brief 
 * 
 * @param in idx 
 * @return liquid_attr_t ==NULL 查询出错,   !NULL 查询ok
 */
liquid_attr_t*  liquid_get_obj(uint8_t idx)   
{
    if( idx>=LIQUID_NODE_NUM_MAX )
    {
        return NULL;
    } 

    return  &liquid_obj[idx];
}



/**
 * @brief liquid_set_obj() 赋值节点数据
 * 
 * @param in idx
 * @param in p_attr
 * @return 0=失败，1=成功 
 */
uint8_t  liquid_set_obj(uint8_t idx,liquid_attr_t* p_attr )  
{
    if( idx>=LIQUID_NODE_NUM_MAX )
    {
        return 0;
    } 

    liquid_obj[idx] = *p_attr;

 return 1 ;

}




/**
 * @brief 
 * 
 * @param attr_id 
 * @param attr_out 
 */
void liquid_get_attr(uint8_t idx,uint16_t attr_id, IotModel* attr_out)
{
    attr_out->iot_id = attr_id;//传给服务器
    

    if( idx > LIQUID_NODE_NUM_MAX )
    {
       logout("error:liquid idx outof range\n"); 
       return ;
    }


    switch(attr_id)
    {
        //////---------RO--------------------------//////////////////////
        case 0x0030:
        {   
            attr_out->value = liquid_obj[idx].data.temper/100;//0x0030	温度	RO	否	运行参数	int8_t	-128~127	1℃
        }  break;

        case 0x0500:
        {    
            attr_out->value = liquid_obj[idx].data.alarm.value;
        }  break;

        case 0x0501:
        {    
            attr_out->value = liquid_obj[idx].data.level_mm;
        }  break;

//0x0502	温度	RO	否	运行参数	int16_t	-32768~32767	0.01℃
        case 0x0502:
        {    
            attr_out->value = liquid_obj[idx].data.temper;
        }  break;


        //////---------RO--------------------------//////////////////////


        //////---------R/W--------------------------//////////////////////
        case 0x0600:
        {
            attr_out->value = liquid_obj[idx].config.addr;
        }  break;

        case 0x0601:
        {
            attr_out->value = liquid_obj[idx].config.alarm_enable.value;
        }  break;

        case 0x0602:
        {
            attr_out->value = liquid_obj[idx].config.channel;
        }  break;

        case 0x0604:
        {
            attr_out->value = liquid_obj[idx].config.under_level_th;
        }  break;

        case 0x0605:
        {
            attr_out->value = liquid_obj[idx].config.over_level_th;
        }  break;


// 0x0606	温度过低阈值	R/W	否	配置参数	int16_t	-32768~32767	0.01℃
// 0x0607	温度过高阈值	R/W	否	配置参数	int16_t	-32768~32767	0.01℃
        case 0x0606:
        {
            attr_out->value = liquid_obj[idx].config.under_temper_th;// 温度过低阈值
        }  break;

        case 0x0607:
        {
            attr_out->value = liquid_obj[idx].config.over_temper_th;
        }  break;

// 0x0608	监测时间	R/W	否	配置参数	uint32_t		sec
// 0x0609	液位异常值	R/W	否	配置参数	uint32_t		0.01mm

        case 0x0608:
        {
            attr_out->value = liquid_obj[idx].config.monitor_sec_th;
        }  break;

        case 0x0609:
        {
            attr_out->value = liquid_obj[idx].config.monitor_level_th;
        }  break;



        // case 0x0486:
        // {
        //     attr_out->value = liquid_obj[idx].config.under_temper_th/100;// 0x0486	温度过低阈值
        // }  break;

        // case 0x0487:
        // {
        //     attr_out->value = liquid_obj[idx].config.over_temper_th/100;
        // }  break;




        //////---------R/W--------------------------//////////////////////



// 0x0801	软件版本
// 0x0802	硬件版本
// 0x0803	产品型号
// 0x0804	生产信息
// 0x0805	厂家信息

        //////---------RO--------------------------//////////////////////
        // case 0x0800://0x0800	产品类型	RO	否	产品类型	uint16_t
        // {
        //     attr_out->value = CTK_PID;
        // }  break;

        case 0x0801:
        {
            attr_out->values.size = strlen(liquid_obj[idx].info.soft_ver);
            strncpy((char*)attr_out->values.bytes,liquid_obj[idx].info.soft_ver,32);
        }  break;
        case 0x0802:
        {
            attr_out->values.size = strlen(liquid_obj[idx].info.hard_ver);
            strncpy((char*)attr_out->values.bytes,liquid_obj[idx].info.hard_ver,32);
        }  break;

        case 0x0803:
        {
            attr_out->values.size = strlen(liquid_obj[idx].info.product_model);
            strncpy((char*)attr_out->values.bytes,liquid_obj[idx].info.product_model,32);
        }  break;

        case 0x0804:
        {
            attr_out->values.size = strlen(liquid_obj[idx].info.production_info);
            strncpy((char*)attr_out->values.bytes,liquid_obj[idx].info.production_info,32);
        }  break;

        case 0x0805:
        {
            attr_out->values.size = strlen(liquid_obj[idx].info.manufacturer);
            strncpy((char*)attr_out->values.bytes,liquid_obj[idx].info.manufacturer,32);
        }  break;
        //////---------RO--------------------------//////////////////////


       default: 
           break;

    }

}

/**
 * @brief 
 * 
 * @param attr_in 
 * @return uint8_t 
 */
uint8_t liquid_set_attr(uint8_t idx,IotModel* attr)
{
uint8_t ret  = 0;

//dev_mod_info_t info;


    //printf_log(lv0,"set addr %04X, value = %d\n", attr->iot_id, attr->value);////printf_log

    logout("set addr %04X, value = %lu\n", attr->iot_id, attr->value);

    if( idx > LIQUID_NODE_NUM_MAX )
    {
       logout("error:liquid idx outof range\n"); 
       return 0;
    }

   //  memset((uint8_t*)&info,0,sizeof(dev_mod_info_t ) );

    // info.node_type = 1;
    // info.channel   = 2;
    // info.chan_addr = 1;

 //    iot_get_mod_info_with_index( idx ,&info);
//got info: chan_addr=1,channel=2,node_type=53254,indx=1
  // info.node_type = 1;

    switch( attr->iot_id )
    {

        //////--------对与上行是只读-RO-----------对与下行是只写-WO--------------------//////////////////////
        case 0x0030:
        {   
            liquid_obj[idx].data.temper = attr->value*100;   //----表示负温度的时候还有问题---0x0030	温度	RO	否	运行参数	int8_t	-128~127	1℃

        }  break;

        case 0x0500:
        {    
            liquid_obj[idx].data.alarm.value = attr->value;
        }  break;

        case 0x0501:
        {    
            liquid_obj[idx].data.level_mm = attr->value;
        }  break;

        case 0x0502:
        {   
            liquid_obj[idx].data.temper = attr->value; 
        }  break;


        //////---------RO--------------------------//////////////////////



        //////---------R/W--------------------------//////////////////////
        case 0x0600:
        {
            liquid_obj[idx].config.addr = attr->value;   /////还需要保存
           // ret  = iot_Node_WriteSensor_one(  1,  0x12, 4,  attr->iot_id,  attr->value);
            ret  = 1;
        }  break;

        case 0x0601:
        {
            liquid_obj[idx].config.alarm_enable.value = attr->value;

            //dpid
            // 0x0601	液位报警使能	 data_type=3
            // 0x0604	液位过低阈值     data_type=4
            // 0x0605	液位过高阈值     data_type=4
            // 0x0486	温度过低阈值     data_type=4
            // 0x0487	温度过高阈值     data_type=4
            //1,0x12, 3 or 4 
            // ret  =iot_Node_WriteSensor_one(  1,  0x12, 3,  attr->iot_id,  attr->value);

             //ret  = json_write_setAttr_dev( &info,"oilLevel_2_1","alarmEn" ,  attr->value );
           // ret  = 1;           
        }  break;

// {"name":"alarmEn","lable":"液位报警使能","val":15},
// {"name":"mbAddr","lable":"地址","val":0},
// {"name":"thOlL","lable":"液位过低阈值","val":30000},
// {"name":"thOlH","lable":"液位过高阈值","val":40000},
// {"name":"thTL","lable":"温度过低阈值","val":10},
// {"name":"thTH","lable":"温度过高阈值","val":22},


        case 0x0602://0x0602	液位设备通道编号
        {
            liquid_obj[idx].config.channel = attr->value;

           // ret  = iot_Node_WriteSensor_one(  1,  0x12, 4,  attr->iot_id,  attr->value);
             //ret  = json_write_setAttr_dev( &info,"oilLevel_2_1","mbAddr" ,  attr->value );
            ret  = 1;
        }  break;

        case 0x0604:
        {
            liquid_obj[idx].config.under_level_th = attr->value;
            // 0x0604	液位过低阈值     data_type=4
           // ret  = iot_Node_WriteSensor_one(  1,  0x12, 4,  attr->iot_id,  attr->value);
          // ret  = json_write_setAttr_dev( &info,"oilLevel_2_1","thOlL" ,  attr->value );  
            ret  = 1;
        }  break;

        case 0x0605:
        {
            liquid_obj[idx].config.over_level_th = attr->value;
             // 0x0605	液位过高阈值     data_type=4
          //  ret  = iot_Node_WriteSensor_one(  1,  0x12, 4,  attr->iot_id,  attr->value);
           //ret  = json_write_setAttr_dev( &info,"oilLevel_2_1","thOlH" ,  attr->value );  
            ret  = 1;
        }  break;



// 0x0606	温度过低阈值	R/W	否	配置参数	int16_t	-32768~32767	0.01℃
// 0x0607	温度过高阈值	R/W	否	配置参数	int16_t	-32768~32767	0.01℃
        case 0x0606:
        {
             liquid_obj[idx].config.under_temper_th = attr->value;// 	温度过低阈值
           // ret  = iot_Node_WriteSensor_one(  1,  0x12, 4,  attr->iot_id,  attr->value);     
             //ret  = json_write_setAttr_dev( &info,"oilLevel_2_1","thTL" ,  attr->value );       
            ret  = 1;           
        }  break;

        case 0x0607:
        {
             liquid_obj[idx].config.over_temper_th = attr->value;
             ret  = 1; 
        }  break;

// 0x0608	监测时间	R/W	否	配置参数	uint32_t		sec
// 0x0609	液位异常值	R/W	否	配置参数	uint32_t		0.01mm

        case 0x0608:
        {          
             liquid_obj[idx].config.monitor_sec_th = attr->value;
             ret  = 1;            
        }  break;

        case 0x0609:
        {
             liquid_obj[idx].config.monitor_level_th = attr->value;
             ret  = 1;             
        }  break;


#if 0 /////旧的iot_id --精度不够----    

// json_write_setAttr_dev( dev_mod_info_t* info,const char* dev_name_str,const char* attr_name_str ,uint32_t attr_val )
        case 0x0486:
        {
            liquid_obj[idx].config.under_temper_th = attr->value*100;// 0x0486	温度过低阈值
           // ret  = iot_Node_WriteSensor_one(  1,  0x12, 4,  attr->iot_id,  attr->value);     
             //ret  = json_write_setAttr_dev( &info,"oilLevel_2_1","thTL" ,  attr->value );       
            ret  = 1;
        }  break;

        case 0x0487:
        {
            liquid_obj[idx].config.over_temper_th = attr->value*100;
            //ret  = iot_Node_WriteSensor_one(  1,  0x12, 4,  attr->iot_id,  attr->value);    
            // ret  = json_write_setAttr_dev( &info,"oilLevel_2_1","thTH" ,  attr->value );       
            ret  = 1;
        }  break;

#endif


        //////---------R/W--------------------------//////////////////////

       default: 
           break;

    }

 return ret;

}



#define  liquid_scale_step           (25U)

void liquid_test_tick_min(uint8_t idx)
{
static uint32_t cnt = 0;
  IotModel attr;
    memset(&attr, 0,  sizeof(IotModel) );

   LOG_NAME();
/////------测试数据-------------------------
    // .data.level_mm = 50728, //0.01mm
    // .data.temper   = 37,    //温度  1℃ 


// 0x0500	液位报警信息
    attr.iot_id =0x0500;
    attr.value =0x0000;
    liquid_set_attr(idx, &attr); 


// 0x0501	液位
    attr.iot_id =0x0501;

   if(cnt < liquid_max_scale_0_01mm/liquid_scale_step)
   {
       attr.value = liquid_max_scale_0_01mm - liquid_scale_step*cnt;
   }else{
       attr.value = 0;
   }


    liquid_set_attr(idx, &attr); 


// 0x0030	温度
    attr.iot_id =0x0030;
    attr.value = 20 + (cnt&0x0F);
    liquid_set_attr(idx, &attr); 
 
    cnt++;

}




//void liquid_update_tick_min(uint8_t idx,uint8_t pattr_size,IotModel* pattr )
////刷新节点运行数据
void liquid_update_tick_min(uint8_t idx,int8_t temper ,uint32_t liquid )
{
  IotModel attr;
  memset(&attr, 0,  sizeof(IotModel) );

   LOG_NAME();



    if( idx > LIQUID_NODE_NUM_MAX )
    {
       logout("error:liquid idx outof range\n"); 
       return ;
    }



//#if 0
liquid_attr_t*  pattr=liquid_get_obj( idx) ; 


  
// 0x0500	液位报警信息
    // attr.iot_id =0x0500;
    // attr.value =0x0000;
    // liquid_set_attr(idx, &attr); 

//---------这里添加报警逻辑------------------------

    if( temper>=pattr->config.over_temper_th )
    {
        pattr->data.alarm.bit.over_temper = 1;

    }else if( temper<=pattr->config.under_temper_th )
    {
        pattr->data.alarm.bit.under_temper = 1;
            
    }else{
        pattr->data.alarm.bit.over_temper  = 0;
        pattr->data.alarm.bit.under_temper = 0;
    }


    if( liquid>=pattr->config.over_level_th )
    {
        pattr->data.alarm.bit.over_level = 1;

    }else if( liquid<=pattr->config.under_level_th )
    {
        pattr->data.alarm.bit.under_level = 1;
            
    }else{
        pattr->data.alarm.bit.over_level  = 0;
        pattr->data.alarm.bit.under_level = 0;
    }

   pattr = NULL;   

//#endif


// 0x0501	液位
    attr.iot_id =0x0501;
    attr.value = liquid;
    liquid_set_attr(idx, &attr); 


// 0x0030	温度
    attr.iot_id =0x0030;
    attr.value  = temper;////负温度的时候有问题----还需要进一步处理
    liquid_set_attr(idx, &attr); 
 
}







////刷新节点运行数据
void liquid_obj_update(uint8_t idx,liquid_attr_t* pliq_in  )
{
  IotModel attr;
  memset(&attr, 0,  sizeof(IotModel) );

   LOG_NAME();

    if( idx > LIQUID_NODE_NUM_MAX )
    {
       logout("error:liquid idx outof range\n"); 
       return ;
    }


    if( NULL==pliq_in )
    {
       logout("error:pliq_in==NULL\n"); 
       return ;
    }



//#if 0
liquid_attr_t*  pattr=liquid_get_obj( idx) ; 

 ////-----保存节点数据到物模型------
      *pattr = *pliq_in;

 //-----同步节点数据到 白名单--------
   iot_set_device_online_state_with_index(idx,  pliq_in->flags.bit.online );   ////同步节点在线标志到 白名单-----

 //-----还有其它数据需要同步到 白名单----通道编号--通道地址???----





#if 0
// 0x0500	液位报警信息
    // attr.iot_id =0x0500;
    // attr.value =0x0000;
    // liquid_set_attr(idx, &attr); 

//---------这里添加报警逻辑------------------------

    if( temper>=pattr->config.over_temper_th )
    {
        pattr->data.alarm.bit.over_temper = 1;

    }else if( temper<=pattr->config.under_temper_th )
    {
        pattr->data.alarm.bit.under_temper = 1;
            
    }else{
        pattr->data.alarm.bit.over_temper  = 0;
        pattr->data.alarm.bit.under_temper = 0;
    }


    if( liquid>=pattr->config.over_level_th )
    {
        pattr->data.alarm.bit.over_level = 1;

    }else if( liquid<=pattr->config.under_level_th )
    {
        pattr->data.alarm.bit.under_level = 1;
            
    }else{
        pattr->data.alarm.bit.over_level  = 0;
        pattr->data.alarm.bit.under_level = 0;
    }

   pattr = NULL;   

//#endif


// 0x0501	液位
    attr.iot_id =0x0501;
    attr.value = liquid;
    liquid_set_attr(idx, &attr); 


// 0x0030	温度
    attr.iot_id =0x0030;
    attr.value  = temper;////负温度的时候有问题----还需要进一步处理
    liquid_set_attr(idx, &attr); 
 
#endif


}










